package com.base.lib.base.view

import android.content.Context
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.IdRes
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.Postcard
import com.alibaba.android.arouter.launcher.ARouter
import com.base.lib.R
import com.base.lib.base.mvvm.view.BaseView
import com.base.lib.base.utils.NetUtil
import com.base.lib.base.widget.LoadingInitView
import com.base.lib.base.widget.LoadingTransView
import com.base.lib.base.widget.NetErrorView
import com.base.lib.base.widget.NoDataView
import com.base.lib.log.KLog
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity
import com.base.lib.base.utils.DensityUtil
import com.base.lib.base.utils.StatusBarUtils
import com.base.lib.base.utils.ext.view.showToast

/**
 * 基础页面
 *
 * @Data 2020/12/3
 */
abstract class BaseFragment : Fragment(), BaseView {

    companion object {
        val TAG: String = this::class.java.simpleName
    }

    protected lateinit var mContext: Context

    protected lateinit var mActivity: RxAppCompatActivity
    protected lateinit var mView: View

    protected var mNetErrorView: NetErrorView? = null
    protected var mNoDataView: NoDataView? = null
    protected var mLoadingInitView: LoadingInitView? = null
    protected var mLoadingTransView: LoadingTransView? = null

    protected lateinit var mViewStubTop: ViewStub
    protected lateinit var mViewStubContent: ViewStub
    protected lateinit var mViewStubInitLoading: ViewStub
    protected lateinit var mViewStubTransLoading: ViewStub
    protected lateinit var mViewStubNoData: ViewStub
    protected lateinit var mViewStubError: ViewStub
    private var isViewCreated = false
    private var isFirst = true

    protected var mToolbar: Toolbar? = null
    protected var rl_toolbar: RelativeLayout? = null
    protected var toolbar_title: TextView? = null
    protected var toolbar_left_image_back: TextView? = null
    protected var toolbar_subtitle: TextView? = null
    protected var toolbar_subtitle_image: ImageView? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        mContext = context
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val currentTimeMillis = System.currentTimeMillis()

        mActivity = (activity as RxAppCompatActivity?)!!
        ARouter.getInstance().inject(this)
        initBundle()

        val totalTime = System.currentTimeMillis() - currentTimeMillis
        KLog.e(TAG, "onCreate: 当前进入的Fragment: $javaClass 初始化时间:$totalTime ms")
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        mView = inflater.inflate(R.layout.fragment_root, container, false)
        initCommonView(mView)
        return mView
    }

    open fun initCommonView(view: View) {
        mToolbar = findViewById(R.id.toolbar);
        rl_toolbar = findViewById<RelativeLayout>(R.id.rl_toolbar)
        toolbar_title = findViewById<TextView>(R.id.toolbar_title)
        toolbar_left_image_back = findViewById<TextView>(R.id.toolbar_left_image_back)
        toolbar_subtitle = findViewById<TextView>(R.id.toolbar_subtitle)
        toolbar_subtitle_image = findViewById<ImageView>(R.id.toolbar_subtitle_image)

        mViewStubTop = view.findViewById(R.id.view_stub_top)
        mViewStubContent = view.findViewById(R.id.view_stub_content)
        mViewStubInitLoading = view.findViewById(R.id.view_stub_init_loading)
        mViewStubTransLoading = view.findViewById(R.id.view_stub_trans_loading)
        mViewStubNoData = view.findViewById(R.id.view_stub_nodata)
        mViewStubError = view.findViewById(R.id.view_stub_error)

        initContentView(mViewStubContent)
    }

    open fun initTopView(intRes: Int) {
        mViewStubTop.layoutResource = intRes
        mViewStubTop.inflate()
    }

    open fun initContentView(mViewStubContent: ViewStub) {
        mViewStubContent.layoutResource = onBindLayout()
        mViewStubContent.inflate()
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView(mView)
        initListener()
        isViewCreated = true
    }

    /**
     * 懒加载机制 当页面可见的时候加载数据
     * 如果当前 FragmentTransaction.setMaxLifecycle 处理 Lifecycle.State.RESUMED 则 懒加载失效
     * 如果 FragmentTransaction.setMaxLifecycle 传入BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT ，
     * 则只有当前的Fragment处于Lifecycle.State.RESUMED状态。 所有其他片段的上限为Lifecycle.State.STARTED 。
     * 如果传递了BEHAVIOR_SET_USER_VISIBLE_HINT ，则所有片段都处于Lifecycle.State.RESUMED状态，
     * 并且将存在Fragment.setUserVisibleHint(boolean)回调
     */
    private fun lazyLoad() {
        //这里进行双重标记判断,必须确保onCreateView加载完毕且页面可见,才加载数据
        KLog.v("MYTAG", "lazyLoad start...")
        KLog.v("MYTAG", "isViewCreated:$isViewCreated")
        KLog.v("MYTAG", "isFirst:$isFirst")
        if (isViewCreated && isFirst) {
            Log.d(TAG, "lazyLoad: Successful")
            initData()
            //数据加载完毕,恢复标记,防止重复加载
            isViewCreated = false
            isFirst = false
        } else {
            Log.d(TAG, "lazyLoad: Fail")
        }
    }

    //默认启用懒加载
    open fun enableLazyData(): Boolean {
        return true
    }

    override fun onResume() {
        super.onResume()
        //如果启用了懒加载就进行懒加载，否则就进行预加载
        if (enableLazyData()) {
            lazyLoad()
        } else {
            initData()
        }
    }

    /**
     * onCreate 初始化
     */
    open fun initBundle() {}

    /**
     * onCreateView 引入界面
     */
    abstract fun onBindLayout(): Int

    /**
     * onViewCreated 界面初始化
     */
    abstract fun initView(mView: View)

    /**
     * onViewCreated 初始化监听
     */
    override fun initListener() {}

    /**
     * onResume 默认懒加载 初始化一次
     */
    abstract override fun initData()

    override fun finishActivity() {
        mActivity.finish()
    }

    override fun showInitLoadView() {
        showInitLoadView(true)
    }

    override fun hideInitLoadView() {
        showInitLoadView(false)
    }

    override fun showTransLoadingView() {
        showTransLoadingView(true)
    }

    override fun hideTransLoadingView() {
        showTransLoadingView(false)
    }

    override fun showNoDataView() {
        showNoDataView(true)
    }

    override fun showNoDataView(resid: Int) {
        showNoDataView(true, resid)
    }

    override fun hideNoDataView() {
        showNoDataView(false)
    }

    override fun showNetWorkErrView() {
        showNetWorkErrView(true)
    }

    override fun hideNetWorkErrView() {
        showNetWorkErrView(false)
    }

    open fun showInitLoadView(show: Boolean) {
        if (mLoadingInitView == null) {
            val view = mViewStubInitLoading.inflate()
            mLoadingInitView = view.findViewById(R.id.view_init_loading)
        }
        mLoadingInitView?.visibility = if (show) View.VISIBLE else View.GONE
        mLoadingInitView?.loading(show)
    }

    open fun showNetWorkErrView(show: Boolean) {
        if (mNetErrorView == null) {
            val view = mViewStubError.inflate()
            mNetErrorView = view.findViewById(R.id.view_net_error)
            mNetErrorView?.setOnClickListener(View.OnClickListener {
                if (!NetUtil.checkNetToast()) {
                    return@OnClickListener
                }
                hideNetWorkErrView()
                initData()
            })
        }
        mNetErrorView?.visibility = if (show) View.VISIBLE else View.GONE
    }

    open fun showNoDataView(show: Boolean) {
        if (mNoDataView == null) {
            val view = mViewStubNoData.inflate()
            mNoDataView = view.findViewById(R.id.view_no_data)
        }
        mNoDataView?.visibility = if (show) View.VISIBLE else View.GONE
    }

    open fun showNoDataView(show: Boolean, resid: Int) {
        showNoDataView(show)
        if (show) {
            mNoDataView?.setNoDataView(resid)
        }
    }

    open fun showTransLoadingView(show: Boolean) {
        if (mLoadingTransView == null) {
            val view = mViewStubTransLoading.inflate()
            mLoadingTransView = view.findViewById(R.id.view_trans_loading)
        }
        mLoadingTransView?.visibility = if (show) View.VISIBLE else View.GONE
        mLoadingTransView?.loading(show)
    }

    open fun startActivity(clz: Class<*>?, bundle: Bundle?) {
        val intent = Intent(activity, clz)
        if (bundle != null) {
            intent.putExtras(bundle)
        }
        startActivity(intent)
    }

    /**
     * 跳转方式
     * 使用方法 startActivity<TargetActivity> { putExtra("param1", "data1") }
     */
    inline fun <reified T> startActivity(block: Intent.() -> Unit) {
        val intent = Intent(context, T::class.java)
        intent.block()
        startActivity(intent)
    }

    /**
     * 阿里路由跳转
     * open("填入你要跳转的ARouter路径") {
     * withString("你要传递extra的key", "你要传递extra的value")
     * }
     */
    open fun open(path: String, block: Postcard.() -> Unit = {}) {
        val postcard = ARouter.getInstance().build(path)
        postcard.block()
        postcard.navigation()
    }

    /**
     * 阿里路由跳转并结束当前页面
     * 建议：切记当前Activity只有一个Frament方式使用使用
     */
    open fun openWithFinish(path: String, block: Postcard.() -> Unit = {}) {
        open(path, block)
        mActivity.finish()
    }

    private var mLastButterKnifeClickTime: Long = 0

    /**
     * 是否快速点击
     *
     * @return true 是
     */
    open fun beFastClick(): Boolean {
        val currentClickTime = System.currentTimeMillis()
        val flag = currentClickTime - mLastButterKnifeClickTime < 400L
        mLastButterKnifeClickTime = currentClickTime
        return flag
    }

    open fun onClick(v: View?) {
    }

    open fun <T : View?> findViewById(@IdRes id: Int): T {
        return mView.findViewById<T>(id)
    }

    //设置顶部toolbar相应样式
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    open fun setTop(
        title: String, subTitle: Any? = null, isBack: (() -> Unit)? = {
            toolbar_left_image_back?.setBackgroundResource(R.drawable.write_back)
            toolbar_left_image_back?.setOnClickListener { requireActivity().onBackPressed() }
        }
    ): TextView? {
        mToolbar?.visibility = View.VISIBLE;
        toolbar_title?.text = title
        toolbar_title?.isSelected = true
        //小窗模式不计算状态栏的高度
        if (!DensityUtil.isSmallWindow(requireActivity())) {
            val layoutParams = mToolbar?.layoutParams
            layoutParams?.height = StatusBarUtils.getStatusBarHeight(requireActivity()) + DensityUtil.dip2px(requireActivity(), 46)
            mToolbar?.layoutParams = layoutParams
        }
        //默认显示返回按钮
        isBack?.invoke()
        //根据subtitle的数据类型来显示图片或文字
        when (subTitle) {
            is String -> {
                toolbar_subtitle_image?.visibility = View.GONE
                toolbar_subtitle?.visibility = View.VISIBLE
                toolbar_subtitle?.text = subTitle
            }
            is Int -> {
                toolbar_subtitle?.visibility = View.GONE
                toolbar_subtitle_image?.visibility = View.VISIBLE
                toolbar_subtitle_image?.setImageResource(subTitle)
            }
            else -> {
                toolbar_subtitle?.visibility = View.GONE
                toolbar_subtitle_image?.visibility = View.GONE
            }
        }
        return toolbar_title;
    }

    //设置顶部toolbar相应样式
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    open fun setTopTitle(subTitle: Any,clickListener: View.OnClickListener? = null): TextView? {
        mToolbar?.visibility = View.VISIBLE;
        //小窗模式不计算状态栏的高度
        if (!DensityUtil.isSmallWindow(requireActivity())) {
            val layoutParams = mToolbar?.layoutParams
            layoutParams?.height =
                StatusBarUtils.getStatusBarHeight(requireActivity()) + DensityUtil.dip2px(requireActivity(), 46)
            mToolbar?.layoutParams = layoutParams
        }
        //根据subtitle的数据类型来显示图片或文字
        when (subTitle) {
            is String -> {
                toolbar_title?.background = null;
                toolbar_title?.visibility = View.VISIBLE
                toolbar_title?.text = subTitle
            }
            is Int -> {
                toolbar_title?.visibility = View.VISIBLE
                toolbar_title?.setBackgroundResource(subTitle)
                toolbar_title?.text = ""
            }
            is Drawable -> {
                toolbar_title?.visibility = View.VISIBLE
                toolbar_title?.background = (subTitle)
                toolbar_title?.text = ""
            }
            else -> {
                toolbar_title?.visibility = View.GONE
            }
        }
        toolbar_title?.setOnClickListener(clickListener)
        return toolbar_title;
    }

    //设置顶部toolbar相应样式
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    open fun setRight(subTitle: Any,clickListener: View.OnClickListener? = null) {
        //根据subtitle的数据类型来显示图片或文字
        when (subTitle) {
            is String -> {
                toolbar_subtitle_image?.visibility = View.GONE
                toolbar_subtitle?.visibility = View.VISIBLE
                toolbar_subtitle?.text = subTitle
            }
            is Int -> {
                toolbar_subtitle?.visibility = View.GONE
                toolbar_subtitle_image?.visibility = View.VISIBLE
                toolbar_subtitle_image?.setImageResource(subTitle)
            }
            is Drawable -> {
                toolbar_subtitle?.visibility = View.GONE
                toolbar_subtitle_image?.visibility = View.VISIBLE
                toolbar_subtitle_image?.setImageDrawable(subTitle)
            }
            else -> {
                toolbar_subtitle?.visibility = View.GONE
                toolbar_subtitle_image?.visibility = View.GONE
            }
        }
        rl_toolbar?.setOnClickListener(clickListener)
    }

    //设置顶部toolbar相应样式
    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    open fun setLeft(subTitle: Any,clickListener: View.OnClickListener? = null) {
        //根据subtitle的数据类型来显示图片或文字
        when (subTitle) {
            is String -> {
                toolbar_left_image_back?.background = null;
                toolbar_left_image_back?.visibility = View.VISIBLE
                toolbar_left_image_back?.text = subTitle
            }
            is Int -> {
                toolbar_left_image_back?.visibility = View.VISIBLE
                toolbar_left_image_back?.setBackgroundResource(subTitle)
                toolbar_left_image_back?.text = ""
            }
            is Drawable -> {
                toolbar_left_image_back?.visibility = View.VISIBLE
                toolbar_left_image_back?.background = (subTitle)
                toolbar_left_image_back?.text = ""
            }
            else -> {
                toolbar_left_image_back?.visibility = View.GONE
            }
        }
        toolbar_left_image_back?.setOnClickListener(clickListener)
    }


    protected fun toast(s: String) {
        s.showToast()
    }
}
